import {
  Form, message, Modal, Select, Input,
} from 'antd'
import React, { PureComponent } from 'react'
import {
  getDataSourceDetailById,
  getSchemas,
  saveDgraph,
  saveHBase,
  saveHDFS,
  saveHive,
  saveIoTDB,
  saveKafka,
  saveMaxCompute,
  saveMongo,
  saveMqtt,
  saveOpentsdb,
  saveRdbms,
  saveInfluxDB,
  addProject,
} from './api'
import {
  Dgraph,
  HBase,
  HDFS,
  Hive,
  IoTDB,
  Kafka,
  MaxCompute,
  Mongodb,
  MQTT,
  MySQL,
  OpenTSDB,
  Oracle,
  PostgreSQL,
  Rdbms,
  Sap,
  TiDB,
  InfluxDB,
} from './model'
import JSEncrypt from '@/utils/JSEncrypt.js'
import { buildJDBCLink } from '@/utils/helper.js'

const { Item } = Form
const { Option } = Select

const saveApi = {
  Hive: saveHive,
  MQTT: saveMqtt,
  Mongodb: saveMongo,
  Kafka: saveKafka,
  HBase: saveHBase,
  MySQL: saveRdbms,
  PostgreSQL: saveRdbms,
  SQLServer: saveRdbms,
  DB2: saveRdbms,
  Oracle: saveRdbms,
  Sap: saveRdbms,
  KINGBASE8: saveRdbms,
  DM: saveRdbms,
  TiDB: saveRdbms,
  HDFS: saveHDFS,
  MaxCompute: saveMaxCompute,
  OpenTSDB: saveOpentsdb,
  Dgraph: saveDgraph,
  IoTDB: saveIoTDB,
  AS400: saveRdbms,
  InfluxDB: saveInfluxDB,
}

export default class DataSource extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      // loading: false,
      visible: false,
      allValues: {
        dsType: 'Hive',
      },
      dsType: 'Hive',
      schema: [],
      fileList: [],
      data: {},
    }
    this.form = React.createRef()
  }

  componentDidMount() {
    const { id } = this.props
    if (id) {
      this.getDataSourceDetailByIdFn(id)
    }
  }

  getDataSourceDetailByIdFn = (id) => {
    getDataSourceDetailById({ id }).then((data) => {
      this.setState({
        dsType: data.dsType,
        data,
      }, () => {
        (data.dsType === 'PostgreSQL' || data.dsType === 'KINGBASE8' || data.dsType === 'Sap') && data.password && data.dsLink && data.username ? getSchemas({
          password: data.password,
          dsLink: data.dsLink,
          dsType: data.dsType,
          username: data.username,
        }).then((value) => {
          this.setState({
            schema: value,
          })
        }) : null
        const rdbmsConfig = {
          dbName: data.rdbmsConfig && data.rdbmsConfig.dbName,
          oracleConnectionType: data.rdbmsConfig && data.rdbmsConfig.oracleConnectionType,
          port: data.rdbmsConfig && data.rdbmsConfig.port,
          schema: data.rdbmsConfig && data.rdbmsConfig.schema,
          server: data.rdbmsConfig && data.rdbmsConfig.server,
        }
        const influxDBConfig = {
          dbName: data.rdbmsConfig && data.rdbmsConfig.dbName,
          orgName: data.rdbmsConfig && data.rdbmsConfig.schema,
          server: data.rdbmsConfig && data.rdbmsConfig.server,
          apiToken: JSEncrypt(data.password, true),
        }
        const type = {
          Hive: {
            dbName: data.hiveConfig && data.hiveConfig.dbName,
            hiveSiteAddress: data.hiveConfig && data.hiveConfig.hiveSiteAddress,
            originalFilename: data.hiveConfig && data.hiveConfig.originalFilename,
            port: data.hiveConfig && data.hiveConfig.port,
            server: data.hiveConfig && data.hiveConfig.server,
            files: {
              file: {
                uid: '-1',
                status: 'done',
                type: 'text/xml',
                name: data.hiveConfig && data.hiveConfig.originalFilename,
              },
              fileList: [{
                uid: '-1',
                status: 'done',
                type: 'text/xml',
                name: data.hiveConfig && data.hiveConfig.originalFilename,
              }],
            },
          },
          Mongodb: {
            authDbName: data.mongoConfig && data.mongoConfig.authDbName,
            port: data.mongoConfig && data.mongoConfig.port,
            server: data.mongoConfig && data.mongoConfig.server,
          },
          HDFS: {
            port: data.hdfsConfig && data.hdfsConfig.port,
            server: data.hdfsConfig && data.hdfsConfig.server,
          },
          MySQL: rdbmsConfig,
          PostgreSQL: rdbmsConfig,
          TiDB: rdbmsConfig,
          SQLServer: rdbmsConfig,
          DB2: rdbmsConfig,
          Oracle: rdbmsConfig,
          Sap: rdbmsConfig,
          KINGBASE8: rdbmsConfig,
          DM: rdbmsConfig,
          IoTDB: rdbmsConfig,
          InfluxDB: influxDBConfig,
          MaxCompute: {
            tunnelEndPoint: data.maxComputeConfig && data.maxComputeConfig.tunnelEndPoint,
            endPoint: data.maxComputeConfig && data.maxComputeConfig.endPoint,
            project: data.maxComputeConfig && data.maxComputeConfig.project,
            accessKey: data.maxComputeConfig && data.maxComputeConfig.accessKey,
            accessId: data.maxComputeConfig && data.maxComputeConfig.accessId,
          },
        }

        this.form.current.setFieldsValue({
          connectionProperty: data.connectionProperty,
          dsType: data.dsType,
          dsDesc: data.dsDesc,
          dsLink: data.dsLink,
          dsName: data.dsName,
          dbName: data.dbName,
          password: this.props.title === '查看数据源' || this.props.title === '编辑数据源' ? '******' : null,
          username: data.username,
          ...type[data.dsType],
        })
        if (data.dsType === 'Hive') {
          this.setState({
            fileList: [{
              uid: '-1',
              status: 'done',
              type: 'text/xml',
              name: data.hiveConfig && data.hiveConfig.originalFilename,
            }],
          })
        }
      })
    })
  }

  // eslint-disable-next-line react/no-unused-class-component-methods
  openModal = () => {
    this.form.current && this.form.current.resetFields()
    this.setState({ visible: true })
  }

  closeModal = () => {
    this.props.clearIndex()
    this.setState({ visible: false })
  }

  // 保存编辑
  onConfirm = () => {
    const { data } = this.state
    this.form.current.validateFields().then(values => {
      const {
        name, description, dsType, dsLink, ...others
      } = values
      this.setState({
        loding: true,
      })
      const pass = values.password === '******' ? data.password : JSEncrypt(values.password)
      // if(id: this.props.id) {}
      addProject({
        project: {
          name,
          description,
        },
        storage: {
          password: values.password ? pass : null,
          storageType: values.dsType,
          storageLink: values.dsLink,
          ...others,
        },
      }).then(
        (res) => {
          if (res.status === 200) {
            this.setState({
              visible: false,
              loding: false,
            })
            this.props.clearTable()
            message.success(res.msg)
          } else {
            this.setState({
              loding: false,
            })
            message.error(res.msg)
          }
        },
        (error) => {
          this.setState({
            loding: false,
          })
        },
      )
    })
  }

  valuesChange = (value, allValues) => {
    const key = Object.keys(value)[0]
    if (key === 'dsType') {
      this.form.current.setFieldsValue({
        dsLink: undefined,
      })
    }

    this.setState({
      allValues,
      dsType: allValues.dsType,
    })

    clearTimeout(this.time)
    this.time = setTimeout(() => {
      const newValues = this.form.current?.getFieldsValue(true)
      if ((newValues.dsType === 'PostgreSQL' || newValues.dsType === 'KINGBASE8' || newValues.dsType === 'Sap')
          && newValues.password
          && newValues.server
          && newValues.port
          && newValues.dbName
          && newValues.username
        ) {
        getSchemas({
          password: JSEncrypt(newValues.password),
          dsLink: newValues.dsLink,
          dsType: newValues.dsType,
          username: newValues.username,
        }).then((data) => {
          this.setState({
            schema: data,
          })
        })
      }
    }, 500)

    let type = allValues.dsType
    if (type === 'Oracle' && allValues.oracleConnectionType === 1) {
      type = 'Oracle:ServiceName'
    }
    let connectionProperty = allValues.connectionProperty
    if (allValues.dsType === 'MySQL') {
      connectionProperty = allValues.connectionProperty ? allValues.connectionProperty : 'useUnicode=true&characterEncoding=UTF-8&useSSL=false'
    }
    if (type === 'Kafka' || type === 'OpenTSDB' || type === 'MQTT' || type === 'Dgraph' || type === 'HBase') return
    this.form.current.setFieldsValue({
      dsLink: buildJDBCLink(type, {
        server: allValues.server,
        port: allValues.port,
        dbName: allValues.dbName,
        connectionProperty,
      }),
    })
  }

  render() {
    const {
      visible, allValues, schema, dsType, fileList, loding, data,
    } = this.state
    const {
      isCheck, title, dsTypes, id, clearTable, index,
    } = this.props
    const dataSourceObj = {
      Hive: <Hive data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} fileList={fileList} index={index} />,
      PostgreSQL: <PostgreSQL data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} schema={schema} index={index} />,
      TiDB: <TiDB data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      MySQL: <MySQL data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      SQLServer: <Rdbms data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      DB2: <Rdbms data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      Oracle: <Oracle data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      Sap: <Sap data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} schema={schema} />,
      KINGBASE8: <Rdbms data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} schema={schema} />,
      DM: <Rdbms data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      MaxCompute: <MaxCompute data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      HBase: <HBase data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      Mongodb: <Mongodb data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      HDFS: <HDFS data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      OpenTSDB: <OpenTSDB data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      MQTT: <MQTT data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      Dgraph: <Dgraph data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      Kafka: <Kafka data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      IoTDB: <IoTDB data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
      AS400: <Rdbms data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} type="as400" />,
      InfluxDB: <InfluxDB data={data} clearTable={clearTable} id={id} isCheck={isCheck} form={this.form} index={index} />,
    }
    return (
      <Modal
        title={title}
        visible={visible}
        confirmLoading={loding}
        destroyOnClose
        width={520}
        height={520}
        onCancel={this.closeModal}
        maskClosable={false}
        onOk={this.onConfirm}
        bodyStyle={{
          height: `${document.documentElement.clientHeight * 0.65}px`,
          overflowY: 'auto',
        }}
        okButtonProps={{
          disabled: isCheck,
        }}
      >
        <Form
          ref={this.form}
          labelCol={{ span: 6 }}
          wrapperCol={{ span: 18 }}
          initialValues={{
            abled: true,
          }}
          onValuesChange={this.valuesChange}
        >
          <Item
            label="数据源类型"
            name="dsType"
            initialValue={allValues.dsType}
            rules={[{ required: true, message: '请选择数据源类型' }]}
          >
            <Select
              disabled={isCheck}
              placeholder="请选择数据源类型"
              onChange={(value) => {
              this.form.current && this.form.current.resetFields()
              this.form.current.setFieldsValue({
                dsType: value,
              })
            }}
            >
              {dsTypes && dsTypes.map((obj) => (
                <Option
                  value={obj.id}
                >
                  {obj.name}
                </Option>
              ))}
            </Select>
          </Item>
          <Item
            label="空间名称"
            name="name"
            rules={[{ required: true, message: '请输入空间名称' }]}
          >
            <Input placeholder="请输入空间名称" />
          </Item>
          <Item
            label="空间描述"
            name="description"
            rules={[{ required: true, message: '请输入空间描述' }]}
          >
            <Input.TextArea placeholder="请输入空间名称" />
          </Item>
          {dataSourceObj[dsType]}
        </Form>
      </Modal>
    )
  }
}
